package net.vsame.url2sql.web;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.vsame.url2sql.domain.UrlConfig;
import net.vsame.url2sql.helper.WebHelper;
import net.vsame.url2sql.web.bigpipe.BigPipeHelper;
import net.vsame.url2sql.web.bigpipe.BigpipeDataHelper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class Url2SqlFilter implements Filter {
	
	private static Log LOG = LogFactory.getLog(Url2SqlFilter.class);
	private static String realPath;
	private static String encoding = "utf-8";

    public Url2SqlFilter() {
    }

	public void destroy() {
	}

	public void doFilter(ServletRequest _req, ServletResponse _resp, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) _req;
		HttpServletResponse response = (HttpServletResponse) _resp;
		// 设置编码
		request.setCharacterEncoding(encoding);
		response.setCharacterEncoding(encoding);
		boolean[] isHandled = new boolean[]{false};
		try{
			WebHelper.init(request, response);
			handel(request.getRequestURI().substring(request.getContextPath().length()), request, response, isHandled);
		}finally{
			WebHelper.remove();
		}
		if(!isHandled[0]){
			chain.doFilter(request, response);
		}
	}

	private void handel(String requestURI, HttpServletRequest request,
			HttpServletResponse response, boolean[] isHandled) {
		boolean json = requestURI.endsWith(".json");
		boolean jsonp = requestURI.endsWith(".jsonp");
		if (json){
			requestURI = requestURI.substring(0, requestURI.length() - 5);
		}
		else if (jsonp){
			requestURI = requestURI.substring(0, requestURI.length() - 6);
		}
		if(requestURI.indexOf(".")!= -1){//包含点说明即不为*.json *.jsonp *.html
			return ;
		}
		
		int i = requestURI.lastIndexOf("/");
		String parent = requestURI.substring(0, i);
		//取得当前
		String target = requestURI;
		String restfulParam = "";
		UrlConfig c = UrlSqlMappingHelper.getConfig(target);
		if(c==null){
			target = parent;
			restfulParam = requestURI.substring(i+1);
			c = UrlSqlMappingHelper.getConfig(target);
		}
		//设置参数
		WebHelper.setRestfulParam(target, restfulParam, c);
		
		PrintWriter out = null;
		try {
			out = response.getWriter();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		
		if(json || jsonp){
			response.setContentType("application/x-javascript; charset="+encoding);
			if(json){
				out.print(getJosn(c));
			}else{
				out.print(getJosnp(request, c));
			}
		}
		else {
			//对应的html是否存在，不存在直接return 
			File f = new File(realPath + target + ".html");
			if(!f.exists()){
				return ;
			}else{
				out.println(BigPipeHelper.readHtml(f, parent, true));
			}
			out.println("<script type=\"text/javascript\">");
			out.println(getJosnp(request, c));
			out.print("</script></html>");
		}
		isHandled[0] = true;
		out.flush();
	}

	private String getJosnp(HttpServletRequest request, UrlConfig c) {
		String method = request.getParameter("callback");
		method = method == null ? "callback" : method;
		String str = ";" + method + "(";
		return str + getJosn(c) + ");";
	}

	private String getJosn(UrlConfig c) {
		if(BigpipeDataHelper.hasError()){
			//已包含错误
		}else if(c==null){
			//API不存在
			BigpipeDataHelper.put404();
		}else if(c.getStatus()!=1){
			BigpipeDataHelper.putError(-7, "disabled");
		}else {
			//调用
			try{
				Url2SqlCore.handel();
			}catch(Exception e){
				BigpipeDataHelper.error(e, null);
			}
		}
		return JSON.toJSONString(BigpipeDataHelper.getMap(), SerializerFeature.WriteDateUseDateFormat);
	}

	public void init(FilterConfig config) throws ServletException {
		realPath = config.getServletContext().getRealPath("");
		encoding = config.getInitParameter("encoding");
		// 默认编码为UTF-8
		if (encoding == null || "".equals(encoding)) {
			encoding = "UTF-8";
		}
		LOG.debug("初始化:encoding:" + encoding);
		//初始化表
		
		UrlSqlMappingHelper.init();
		UrlSqlMappingHelper.reload();
		WebHelper.remove();
	}
	
	public static String getEncoding() {
		return encoding;
	}

}
